package modelo;

import modelo.GeneradorDeEscenarios;
import modelo.GeneradorDeEscenariosDePrueba;
import modelo.GeneradorDeEscenariosReal;
import excepciones.LaPosicionYaTieneMinaExcepcion;
import excepciones.TableroIndiceFueraDeRangoExcepcion;
import fiuba.algo3.titiritero.modelo.ObjetoVivo;

import java.util.Collection;
import java.util.Iterator;
import java.util.ArrayList;

public class Juego implements ObjetoVivo {
	private Collection<Barco> barcos;
	private Collection<Mina> minas;
	private Jugador jugador;
	private Tablero tablero;
	private int contadorDeLoops;
	private final int CANTIDAD_DE_PUNTOS_INICIAL = 10000;
	
	public enum Modo {
		PRUEBA
	};
	
	private void crearJuego(GeneradorDeEscenarios generadorDeEscenarios) {
		tablero = new Tablero();
		barcos = generadorDeEscenarios.generarEscenario(tablero);
		minas = new ArrayList<Mina>();
		jugador = new Jugador(CANTIDAD_DE_PUNTOS_INICIAL);
		contadorDeLoops = 0;
	}
	
	public Juego() {
		GeneradorDeEscenarios generadorDeEscenariosReal = new GeneradorDeEscenariosReal();
		crearJuego(generadorDeEscenariosReal);
	}
	
	public Juego(Modo modo) {
		GeneradorDeEscenarios generadorDeEscenarios = null;
		
		if (modo == Modo.PRUEBA) {
      		generadorDeEscenarios = new GeneradorDeEscenariosDePrueba();
      	}

		crearJuego(generadorDeEscenarios);
	}
	
	public int getPuntos() {
		return jugador.getPuntos();
	}
	
	public void pasarTurno() {
      	Iterator<Mina> iteradorDeMinas;
      	Iterator<Barco> iteradorDeBarcos;
      	
        // Avisa a las minas que paso un turno.
        iteradorDeMinas = minas.iterator();
        while (iteradorDeMinas.hasNext()) {
         		Mina mina = iteradorDeMinas.next();
         		mina.siguienteTurno();
        }
        
        // Avisa a los barcos que se deben mover.
      	iteradorDeBarcos = barcos.iterator();
      	while (iteradorDeBarcos.hasNext()) {
      		Barco barco = iteradorDeBarcos.next();
      		barco.mover(tablero);
      	}
        
      	// Si un barco esta destruido lo saca de la lista.
      	iteradorDeBarcos = barcos.iterator();
      	while (iteradorDeBarcos.hasNext()) {
      		Barco barco = iteradorDeBarcos.next();
      		if (barco.estaDestruido()) {
      			barco.sacarBarco();
      			iteradorDeBarcos.remove();
      		}
      	}
      	
      	// Si alguna mina puede explotar la hace explotar y la saca de las lista de minas.    	
      	iteradorDeMinas = minas.iterator();
      	while (iteradorDeMinas.hasNext()) {
      		Mina mina = iteradorDeMinas.next();
      		if (mina.puedeExplotar()) {
      			mina.explotar(tablero);
      			iteradorDeMinas.remove();
      		}
      	}
      	jugador.pasarTurno();
	}
      	
	public boolean perdio() {
		return jugador.perdio();
	}
	
	public boolean gano() {
		return barcos.isEmpty();
	}
	
	public void seleccionarMina(Mina unaMina) {
		jugador.setMina(unaMina);
     }
      
	public Mina ponerMina(int fila, int columna) throws LaPosicionYaTieneMinaExcepcion {
		Mina minaPuesta = null;
        try {
        	// Le da una posicion a la mina y la guarda en la coleccion de minas.
        	minaPuesta = jugador.ponerMina(tablero.getPosicion(fila, columna));
        	minas.add(minaPuesta);
        }
        catch (TableroIndiceFueraDeRangoExcepcion unError) { }
        return minaPuesta;
	}

	public Collection<Barco> getBarcos() {
		return barcos;
	}

	public boolean minaYaPuesta(int fila, int columna){
		Posicion posicion = null;
		try {
			posicion=tablero.getPosicion(fila, columna);
		}
		catch (TableroIndiceFueraDeRangoExcepcion e){ }
		
		Iterator<Mina> iteradorDeMinas=minas.iterator();
		boolean hayUnaMina = false;
		 
		while(iteradorDeMinas.hasNext()){
			Mina mina = iteradorDeMinas.next();
			if(mina.getPosicion() == posicion){
				hayUnaMina = true;
			}
		}
		return hayUnaMina;
	}
	
	public void vivir() {
		contadorDeLoops++;
		if (contadorDeLoops == 50) {
			pasarTurno();
			contadorDeLoops = 0;
		}	
	}
}
